package com.vesystem.vegua.utils;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.vesystem.vegua.config.GlobalConfig;
import com.vesystem.vegua.config.ServerListener;
import com.vesystem.vegua.exceptionConfig.ErrorCode;
import com.vesystem.vegua.exceptionConfig.ParameterInvalid;
import com.vesystem.vegua.modules.common.entity.RemoteApp;
import com.vesystem.vegua.modules.common.entity.SysUser;
import com.vesystem.vegua.modules.common.mapper.RemoteAppMapper;
import com.vesystem.vegua.modules.common.mapper.SysUserMapper;
import com.vesystem.vegua.utils.uamUtils.CodeUtils;
import com.vesystem.vegua.utils.uamUtils.RdpParameter;
import org.apache.guacamole.protocol.GuacamoleClientInformation;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.security.GeneralSecurityException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @auther hcy
 * @create 2020-12-08 17:36
 * @Description
 */
public class TunnelTools {
    private static final Logger log = LoggerFactory.getLogger(TunnelTools.class);
    public static GuacamoleConfiguration createGuaConfigAboutUam(Map<String, List<String>> parameterMap){
        String payload = parameterMap.get("payload").get(0);
        String windowsWidth = parameterMap.get("width").get(0);
        String windowsHeight = parameterMap.get("height").get(0);
        String jsonString = null;
        try {
            jsonString = CodeUtils.getPlaintextFromHex(payload);
        } catch (GeneralSecurityException e) {
            throw new ParameterInvalid(ErrorCode.METHOD_ARGUMENT_NOT_VALID);
        }
        RdpParameter rdpParameter = JSONUtil.toBean(jsonString, RdpParameter.class);
        GuacamoleConfiguration config = new GuacamoleConfiguration();
        config.setProtocol("rdp");
        config.setParameter("width", windowsWidth);
        config.setParameter("height", windowsHeight);
        config.setParameter("enable-font-smoothing", "true");
        config.setParameter("resize-method", "display-update");
        config.setParameter("security", GlobalConfig.PROXY_RDP_SECURITY);
        config.setParameter("ignore-cert", "true");
        config.setParameter("client-name", "UAM_网页客户端");
        config.setParameter("hostname", rdpParameter.getIp());
        config.setParameter("port", rdpParameter.getPort());
        config.setParameter("domain", rdpParameter.getDomain());
        config.setParameter("username", rdpParameter.getUserName());
        String password = rdpParameter.getPasswordMD5();
        password = Objects.equals(password, "") || Objects.equals(password, "******") ? CodeUtils.generateMd5Password(rdpParameter.getUserName()) : password;
        config.setParameter("password", password);
        if (rdpParameter.getRegName() != null && !"".equals(rdpParameter.getRegName())) {
            config.setParameter("remote-app", "||" + rdpParameter.getRegName());
        }
        return config;
    }

    public static GuacamoleConfiguration createGuaConfigAboutGua(String windowsWidth,String widnowsHeight,RemoteApp app){
        GuacamoleConfiguration config = new GuacamoleConfiguration();
        switch (app.getProtocol()){
            case 1:
                log.info("rdp协议");
                config.setProtocol("rdp");
                config.setParameter("username", app.getRemoteLoginname());
                config.setParameter("password", app.getRemotePassword());
                config.setParameter("hostname", app.getRemoteIp());
                config.setParameter("port", app.getRemotePort().toString());
                config.setParameter("domain", app.getDomain());
                config.setParameter("ignore-cert", "true");
                config.setParameter("width", windowsWidth);
                config.setParameter("height", widnowsHeight);
                // 屏幕录像
                if (ServerListener.REMOTE_MOITORING.contains( app.getId() )){
                    config.setParameter("recording-path", "rdpVideo");
                    config.setParameter("create-recording-path", "true");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH-mm-ss");
                    config.setParameter("recording-name", sdf.format(new Date())+"@"+app.getRemoteAlias());
                }
                if ( !StringUtils.isEmpty( app.getAppPath() )){
                    config.setParameter("remote-app", app.getAppPath());
                }
                if ( !StringUtils.isEmpty( app.getAppArgs() )){
                    config.setParameter("remote-app-args", app.getAppArgs());
                }
                if ( !StringUtils.isEmpty( app.getAppDir() )){
                    config.setParameter("remote-app-dir", app.getAppDir());
                }
                return config;
            case 2:
                log.info("ssh协议");
                config.setProtocol("ssh");
                config.setParameter("hostname", app.getRemoteIp());
                config.setParameter("port",app.getRemotePort().toString());
                config.setParameter("username",app.getRemoteLoginname());
                config.setParameter("password",app.getRemotePassword());
                config.setParameter("width", windowsWidth);
                config.setParameter("height", widnowsHeight);
                // 屏幕录像
                if (ServerListener.REMOTE_MOITORING.contains( app.getId() )){
                    config.setParameter("typescript-path", "sshVideo");
                    config.setParameter("create-typescript-path", "true");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH-mm-ss");
                    config.setParameter("typescript-name", sdf.format(new Date())+"@"+app.getRemoteAlias());
                }
                return config;
            case 3:
                log.info("vnc协议");
                break;
            default:
                log.info("未知协议");
        }
        return null;
    }

    public static GuacamoleClientInformation createClientConfig(String config){
        GuacamoleClientInformation clientInfo = new GuacamoleClientInformation();
        List<String> audioMime = new ArrayList<>();
        audioMime.add("audio/L8");
        audioMime.add("audio/L16");
        //这个声音支持的搞法是不规范的，正确的做法是前端在websocket握手时将支持类型发送过来。参考官网demo。
        clientInfo.getAudioMimetypes().addAll(audioMime);
        return clientInfo;
    }


}
